﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKCodeBase.TopologySuite;
using YJKRevitCode.RevitTopologySuite;

namespace YJKRevitCode.SampleAndTest
{
	[Transaction(TransactionMode.Manual)]
	public class CmdRevitFilledRegionTopology : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			UIApplication application = commandData.Application;
			Application application2 = commandData.Application.Application;
			UIDocument activeUIDocument = application.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Reference reference = activeUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "选择第一个FilledRegion");
			Reference reference2 = activeUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "选择第二个FilledRegion");
			FilledRegion filledRegion = document.GetElement(reference.ElementId) as FilledRegion;
			FilledRegion filledRegion2 = document.GetElement(reference2.ElementId) as FilledRegion;
			RevitPolygonDataBean polygonDataFromFilledRegion = this.GetPolygonDataFromFilledRegion(filledRegion);
			RevitPolygonDataBean polygonDataFromFilledRegion2 = this.GetPolygonDataFromFilledRegion(filledRegion2);
			List<RevitPolygonDataBean> lstAllResult = null;
			RevitPolygonBooleanOperater revitPolygonBooleanOperater = new RevitPolygonBooleanOperater();
			if (revitPolygonBooleanOperater.TryGetBooleanResult(polygonDataFromFilledRegion, polygonDataFromFilledRegion2, BooleanOperatorKindEnum.Union, out lstAllResult))
			{
				Transaction transaction = new Transaction(document, "test");
				transaction.Start();
				FilledRegionType useType = CmdRevitFilledRegionTopology.FindFilledRegionType(document);
				CmdRevitFilledRegionTopology.CreatFilledRegion(document, lstAllResult, useType);
				document.Delete(filledRegion.Id);
				document.Delete(filledRegion2.Id);
				transaction.Commit();
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public static FilledRegionType FindFilledRegionType(Autodesk.Revit.DB.Document doc)
		{
			FilledRegionType result = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			List<FilledRegionType> list = filteredElementCollector.OfClass(typeof(FilledRegionType)).ToElements().ToList<Element>().Cast<FilledRegionType>().ToList<FilledRegionType>();
			foreach (FilledRegionType filledRegionType in list)
			{
				if (filledRegionType != null)
				{
					result = filledRegionType;
					break;
				}
			}
			return result;
		}

		public static void CreatFilledRegion(Autodesk.Revit.DB.Document doc, List<RevitPolygonDataBean> lstAllResult, FilledRegionType useType)
		{
			foreach (RevitPolygonDataBean revitPolygonDataBean in lstAllResult)
			{
				List<CurveLoop> list = new List<CurveLoop>();
				if (revitPolygonDataBean.ShellCurveLoop == null)
				{
					using (List<Curve>.Enumerator enumerator2 = revitPolygonDataBean.LstRevitCurve.GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							Curve curve = enumerator2.Current;
							doc.Create.NewDetailCurve(doc.ActiveView, curve);
						}
						continue;
					}
				}
				list.Add(revitPolygonDataBean.ShellCurveLoop);
				if (revitPolygonDataBean.LstHolesCurveLoop != null)
				{
					list.AddRange(revitPolygonDataBean.LstHolesCurveLoop);
				}
				try
				{
					FilledRegion.Create(doc, useType.Id, doc.ActiveView.Id, list);
				}
				catch (Exception)
				{
				}
			}
		}

		private RevitPolygonDataBean GetPolygonDataFromFilledRegion(FilledRegion input)
		{
			CurveLoop curveLoop = new CurveLoop();
			List<CurveLoop> list = null;
			Solid solid = input.get_Geometry(new Options()).ElementAt(0) as Solid;
			if (null == solid || solid.Faces.Size != 1)
			{
				throw new ArgumentException();
			}
			PlanarFace planarFace = solid.Faces.get_Item(0) as PlanarFace;
			foreach (object obj in planarFace.EdgeLoops.get_Item(0))
			{
				curveLoop.Append((obj as Edge).AsCurve());
			}
			if (planarFace.EdgeLoops.Size > 1)
			{
				list = new List<CurveLoop>();
				CurveLoop curveLoop2 = null;
				for (int i = 1; i < planarFace.EdgeLoops.Size; i++)
				{
					curveLoop2 = new CurveLoop();
					foreach (object obj2 in planarFace.EdgeLoops.get_Item(i))
					{
						curveLoop2.Append((obj2 as Edge).AsCurve());
					}
					list.Add(curveLoop2);
				}
			}
			return new RevitPolygonDataBean(curveLoop, list);
		}
	}
}
